/*
 * JUnit Test for Controller: getReviewerEmail(), getSubProgramChairEmail()
 * By: Ching-Ting Huang
 * Last Edit: 5/18/13
 * 
 * Covered methods in Controller.java:
 * 1. getReviewerEmailAddresses()
 * 2. getSubProgramChairEmailAddresses()
 * 3. setCurrentUser()
 * 
 * Covered methods in User.java:
 * 1. addSPCPaper()
 * 2. addReviewer()
 * 3. setPCPaper()
 * 4. setPermission()
 */
package JUnitTests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import Model.Conference;
import Model.Controller;
import Model.Deadline;
import Model.Paper;
import Model.User;

/**
 * Testing methods in the Controller class: getReviewerEmail(), getSubProgramChairEmail().
 * 
 * @author Ching-Ting Huang
 * @version UWT Spring 2013, May 18th. 
 * @group 3-squared-software-systems
 */
public class MailFileTest {

	private static final int REVIEWER = 1;
	private static final int SPC = 2;
	private static final int NUM_PAPER = 3;
	private static final int ASCII_A = 65;
	private static final int ASCII_P = 80;
	private Conference conference;
	private Controller control;
	private User p_chair;
	private User s_chair;
	private String[] expected_review;
	private String[] expected_spc;

	/**
	 * Construct Model classes and setup expected values.
	 * 
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		final Deadline date = new Deadline(1, 2, 3);
		p_chair = new User("abc", "abc", "abc@yahoo.com", "abc", false);
		s_chair = new User("efg", "efg", "efg@yahoo.com", "efg", false);
		conference = new Conference("Software Development", p_chair, date, date, date, date, date);
		control = new Controller();
		expected_spc = new String[]{"P@yahoo.com,", "Q@yahoo.com,", "R@yahoo.com,"};
		expected_review = new String[]{"A@yahoo.com,", "B@yahoo.com,", "C@yahoo.com,",
									   "A@yahoo.com,", "B@yahoo.com,", "C@yahoo.com,",
									   "A@yahoo.com,", "B@yahoo.com,", "C@yahoo.com,"};
		
		pcSetup();
		spcSetup();
	} //setUp

	/**
	 * Test method for {@link Model.Controller#getReviewerEmailAddresses()}.
	 */
	@Test
	public void testGetReviewerEmailAddresses() {
		boolean check = control.setCurrentUser(s_chair.getLogin(), s_chair.getPassword());
		assertTrue("User exist?", check);
		final File rev_mail = control.getReviewerEmailAddresses();
		assertTrue("File exist?", rev_mail.exists());
		assertTrue("File can read?", rev_mail.canRead());
		assertEquals("File name is?", "RevMail.txt", rev_mail.getName());
		final String[] content = getFileContent(rev_mail.getName());
		assertTrue("Same file content?", Arrays.equals(expected_review, content));
	} //testGetReviewerEmailAddresses

	/**
	 * Test method for {@link Model.Controller#getSubProgramChairEmailAddresses()}.
	 */
	@Test
	public void testGetSubProgramChairEmailAddresses() {
		boolean check = control.setCurrentUser(p_chair.getLogin(), p_chair.getPassword());
		assertTrue("User exist?", check);
		final File spc_mail = control.getSubProgramChairEmailAddresses();
		assertTrue("File exist?", spc_mail.exists());
		assertTrue("File can read?", spc_mail.canRead());
		assertEquals("File name is?", "SPCMail.txt", spc_mail.getName());
		final String[] content = getFileContent(spc_mail.getName());
		assertTrue("Same file content?", Arrays.equals(expected_spc, content)); 
	} //testGetSubProgramChairEmailAddresses

	
	
	
	// ----------------------HELPER METHODS-------------------------------------- //
	
	/**
	 * Program chair setup: change permission, add paper to list
	 */
	private void pcSetup() {
		control.addUserToSystem(p_chair);
		p_chair.setPermission(3, false);
		p_chair.setPCPapers(fillPaperList(SPC));
	} //pcSetup

	/**
	 * Subprogram chair setup: change permission, add paper to list.
	 */
	private void spcSetup() {
		control.addUserToSystem(s_chair);
		s_chair.setPermission(SPC, false);
		final List<Paper> papers = fillPaperList(REVIEWER);
		for (int i = 0; i < papers.size(); i ++) {
			s_chair.addSPCPaper(papers.get(i));
		}
	} //spcSetup
	
	/**
	 * Helper method: generate list of papers for current user (may be PC/SPC) and fill
	 * all SPC and Reviewer information for each paper.
	 * 
	 * @param user is the current user.
	 * @return the list of papers.
	 */
	private List<Paper> fillPaperList(final int role) {
		final List<User> users = getRole(role);
		List<Paper> papers = new ArrayList<Paper>();
		for (int i = 0; i < NUM_PAPER; i++) {
//			final Paper paper = new Paper("path", "author name", "author email", "category",                          // Old version 
// 					  "paper title", "keyword", "abstract", conference);
			final Paper paper = new Paper("path", "category", 
			 		  					  "paper title", "keyword", "abstract", conference, users.get(0));            // If this test doesn't work it's because I changed the Paper class, it's getting the author's info from the passed User object, not the passed strings
			paper.setSPC(users.get(i));
			for (int j = 0; j < users.size(); j++) {
				paper.addReviewer(users.get(j));
			}
			papers.add(paper);
		}
		return papers;
	} //pcPapers
	
	/**
	 * Helper method: create different users based on permission. 
	 * 				  Reviewers: A, B, C
	 * 				  SPCs: P, Q, R
	 * 
	 * @param role is the permission each user will have.
	 * @return array of users to be added to the list.
	 */
	private List<User> getRole(final int role) {
		List<User> users = new ArrayList<User>();
		String name = null;
		User temp = null;
		for (int i = 0; i < NUM_PAPER; i++) {
			if (role == REVIEWER) {
				name = Character.toString((char)(ASCII_A + i));
				
			} else if (role == SPC) {
				name = Character.toString((char)(ASCII_P + i));
			} 
			temp = new User(name, name, name + "@yahoo.com", name);
			temp.setPermission(role, false);
			users.add(temp);
		}
		return users;
	} //getRole
	
	/**
	 * This method pulls contents from the file and store all tokens into an array.
	 * 
	 * @param name is the name of the file.
	 * @return the array of tokens from the file.
	 */
	private String[] getFileContent(final String name) {
		List<String> lines = new ArrayList<String>();
	    try {
		    BufferedReader bufferedReader = new BufferedReader(new FileReader(name));
		    String line = null;
		    while ((line = bufferedReader.readLine()) != null) {
				lines.add(line);
		    }
			bufferedReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	    return lines.toArray(new String[lines.size()]);
	} //getFileContent
} //class
